﻿using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GUI_Web.Models;
using System.Collections.Generic;
using GUI_Web.ServicioUsuarios;
using GUI_Web.ServicioEventos;
using GUI_Web.ServicioDocumentos;
using GUI_Web.Resources;
using System.IO;

namespace GUI_Web.Controllers
{
    public class WebAdminController : Controller
    {
        #region Atributes
        ServiceDocumentContractClient _ServicioDocumentos;
        ServiceEventContractClient _ServicioEventos;
        ServiceUserContractClient _ServicioUsuarios;
        #endregion

        #region Constructor
        /// <summary>
        /// Constructor de la clase
        /// </summary>
        public WebAdminController()
        {
            _ServicioDocumentos = new ServiceDocumentContractClient();
            _ServicioEventos = new ServiceEventContractClient();
            _ServicioUsuarios = new ServiceUserContractClient();
        }
        #endregion

        #region Public methods
        /// <summary>
        /// URL: /WebAdmin/
        /// </summary>
        /// <returns>View</returns>
        public ActionResult WebAdmin()
        {
            return View();
        }

        /// <summary>
        /// URL: /WebAdmin/DocumentAudit/
        /// </summary>
        /// <returns>View</returns>
        public ActionResult DocumentAudit()
        {
            return View();
        }

        /// <summary>
        /// Método que se encarga de capturar la información de filtrado de la búsqueda
        /// para recolectar los documentos que los cumplan, o si no mostrar TODOS los
        /// documentos del sistema
        /// </summary>
        /// <param name="_BtnSearch">Nombre del botón</param>
        /// <param name="userSender">Nombre usuario emisor</param>
        /// <param name="userReciever">Nombre usuario receptor</param>
        /// <param name="department">Nombre departamento</param>
        /// <param name="docType">Nombre tipo documento</param>
        /// <param name="issueDate">Fecha de emisión</param>
        /// <param name="receptionDate">Fecha de recepción</param>
        /// <returns>Se redirige a la otra página con los parámetros debidos</returns>
        [HttpPost]
        public ActionResult SearchDocuments(DocumentAuditModel model)
        {
            return RedirectToAction("DocumentResults", model);
        }

        /// <summary>
        /// URL: /WebAdmin/DocumentAudit/
        /// Método que se encarga de desplegar en pantalla los resultados obtenidos de la búsqueda realizada
        /// </summary>
        /// <param name="docs">Lista de documentos resultantes</param>
        /// <returns>View</returns>
        public ActionResult DocumentResults(DocumentAuditModel model)
        {
            Document[] docs = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                //Conduct a different search if params are empty
                if (!this.IsDocSearchParamsEmpty(model.UserSender, model.UserReciever, model.Department, model.DocumentType, model.IssueDate, model.ReceptionDate))
                    docs = _ServicioDocumentos.GetDocuments(md5User, model.UserSender, model.UserReciever, model.Department, model.DocumentType, model.IssueDate, model.ReceptionDate);
                else
                    docs = _ServicioDocumentos.GetAllDocuments(md5User);
            }
            catch (Exception)
            {
                docs = new Document[1];
                Document doc = new Document();
                doc.DateDelivery = DateTime.Now;
                doc.DocumentConsecutive = 1;
                doc.DocumentName = "a";
                doc.DocumentType = "a";
                doc.UserReceiverName = "a";
                doc.UserSenderName = "a";
                docs[0] = doc;
            }

            //Check the delivered results
            if (docs == null)
            {
                ViewData["Message"] = "Ha ocurrido un error en la búsqueda. Por favor intente de nuevo.";
                return View(new Document[0]);
            }
            else if (docs.Length == 0)
            {
                ViewData["Message"] = "No hay resultados que mostrar.";
                return View(new Document[0]);
            }
            else
                return View(docs);            
        }

        /// <summary>
        /// URL: /WebAdmin/DetallesDocumento/
        /// Método que se encarga de desplegar en pantalla un detalle más completo de un documento
        /// </summary>
        /// <param name="consecutivoDocumento">Consecutivo del documento a buscar</param>
        /// <returns>View</returns>
        public ActionResult DocumentDetails(int consecutivoDocumento)
        {
            Document doc = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                doc = _ServicioDocumentos.GetDocument(md5User, consecutivoDocumento);
                return View(doc);
            }
            catch (Exception)
            {
                doc = new Document();
                doc.DateDelivery = DateTime.Now;
                doc.DocumentConsecutive = 1;
                doc.DocumentName = "a";
                doc.DocumentType = "a";
                doc.UserReceiverName = "a";
                doc.UserSenderName = "a";
                return View(doc);
            }
        }

        /// <summary>
        /// URL: /WebAdmin/DocumentHistory/
        /// Método que se encarga de desplegar en pantalla el historial de un documento
        /// </summary>
        /// <param name="consecutivoDocumento">ID del documento a buscar</param>
        /// <returns>View</returns>
        public ActionResult DocumentHistory(int consecutivoDocumento)
        {
            Event[] historial = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                historial = _ServicioEventos.GetDocumentHistory(md5User, consecutivoDocumento);
                return View(historial);
            }
            catch (Exception) {}

            //Check the delivered results
            if (historial == null)
            {
                ViewData["Message"] = "Ha ocurrido un error. Por favor intente de nuevo.";
                return View(new Event[0]);
            }
            else if (historial.Length == 0)
            {
                ViewData["Message"] = "No hay eventos que mostrar.";
                return View(new Event[0]);
            }
            else
                return View(historial);   
        }

        /// <summary>
        /// Busca el documento a ofrecer para descarga
        /// </summary>
        /// <param name="documendId">ID del documento a descargar</param>
        /// <returns>View</returns>
        public ActionResult DownloadDocument(int consecutivoDocumento)
        {
            //Obtenemos el documento como arreglo de bytes 
            byte[] archivoBytes = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                archivoBytes = _ServicioDocumentos.DownloadDocument(md5User, consecutivoDocumento);
            }
            catch (Exception) {}

            //Check the delivered results
            if (archivoBytes == null)
            {
                ViewData["Message"] = "Ha ocurrido un error. Por favor intente de nuevo.";
                return View();
            }
            else if (archivoBytes.Length == 0)
            {
                ViewData["Message"] = "El archivo se encuenta vacío.";
                return View();
            }
            else
            {
                //Ofrecemos el archivo como descarga
                MemoryStream m = new MemoryStream(archivoBytes);
                Response.Clear();
                Response.AddHeader("Content-Length", archivoBytes.Length.ToString());
                Response.ContentType = "application/doc";
                Response.AddHeader("Expires", "0");
                Response.AddHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
                Response.AddHeader("Pragma", "public");
                Response.AddHeader("Content-Disposition", "attachment; filename=sample.doc");
                Response.BinaryWrite(archivoBytes);
                Response.Flush();
                Response.End();

                return View();
            }

        }

        /// <summary>
        /// URL: /WebAdmin/UserAudit/
        /// </summary>
        /// <returns>View</returns>
        public ActionResult UserAudit()
        {
            return View();
        }

        /// <summary>
        /// Busca los usuarios resultantes
        /// </summary>
        /// <param name="model">Modelo de usuario</param>
        /// <returns>El view con la lista de resultados</returns>
        [HttpPost]
        public ActionResult SearchUsers(UserAuditModel model)
        {
            return RedirectToAction("UserResults", model);
        }

        /// <summary>
        /// URL: /WebAdmin/UserAudit/
        /// Método que se encarga de desplegar en pantalla los resultados obtenidos de la búsqueda realizada
        /// </summary>
        /// <param name="docs">Lista de usuarios resultantes</param>
        /// <returns>View</returns>
        public ActionResult UserResults(UserAuditModel model)
        {

            User[] users = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                //Conduct a different search if params are empty
                if (String.IsNullOrEmpty(model.UserName))
                    users = _ServicioUsuarios.GetUsers(md5User, model.UserName);
                else
                    users = _ServicioUsuarios.GetAllUsers(md5User);
            }
            catch (Exception) {}

            //Check the delivered results
            if (users == null)
            {
                ViewData["Message"] = "Ha ocurrido un error en la búsqueda. Por favor intente de nuevo.";
                return View(new User[0]);
            }
            else if (users.Length == 0)
            {
                ViewData["Message"] = "No hay resultados que mostrar.";
                return View(new User[0]);
            }
            else
                return View(users);   
        }

        /// <summary>
        /// URL: /WebAdmin/DetallesUsuario/
        /// Método que se encarga de desplegar en pantalla un detalle más completo de un usuario
        /// </summary>
        /// <param name="nombreUsuario">Usuario a desplegar</param>
        /// <returns>View</returns>
        public ActionResult UserDetails(string nombreUsuario)
        {
            User usuario = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                usuario = _ServicioUsuarios.GetUser(md5User, nombreUsuario);
                return View(usuario);
            }
            catch (Exception)
            {
                return View(new User());
            }

            
        }

        /// <summary>
        /// URL: /WebAdmin/UserHistory/
        /// Método que se encarga de desplegar en pantalla el historial de un usuario
        /// </summary>
        /// <param name="consecutivoDocumento">ID del documento a buscar</param>
        /// <returns>View</returns>
        public ActionResult UserHistory(string nombreUsuario)
        {
            Event[] historial = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                historial = _ServicioEventos.GetUserHistory(md5User, nombreUsuario);
                return View(historial);
            }
            catch (Exception) {}

            //Check the delivered results
            if (historial == null)
            {
                ViewData["Message"] = "Ha ocurrido un error. Por favor intente de nuevo.";
                return View(new Event[0]);
            }
            else if (historial.Length == 0)
            {
                ViewData["Message"] = "No hay eventos que mostrar.";
                return View(new Event[0]);
            }
            else
                return View(historial);
        }

        /// <summary>
        /// URL: /WebAdmin/IrregularEvents/
        /// </summary>
        /// <returns>View</returns>
        public ActionResult IrregularEvents()
        {

            Event[] eventos = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                //Search for events
                eventos = _ServicioEventos.GetIrregularEvents(md5User);
            }
            catch (Exception) { }

            //Check the delivered results
            if (eventos == null || eventos.Length == 0)
            {
                ViewData["Message"] = "No hay eventos que mostrar.";
                return View(new Event[0]);
            }
            else
                return View(eventos); 
            
        }

        /// <summary>
        /// URL: /WebAdmin/DocumentMigration/
        /// </summary>
        /// <returns>View</returns>
        public ActionResult DocumentMigration()
        {
            Document[] docs = null;
            byte[] md5User = (byte[])Session[Constants.HashUsernamePassword];

            try
            {
                //Search for events
                docs = _ServicioDocumentos.GetDocumentsToMigrate(md5User);
            }
            catch (Exception) {}

            //Check the delivered results
            if (docs == null || docs.Length == 0)
            {
                ViewData["Message"] = "No hay documentos por migrar.";
                return View(new Document[0]);
            }
            else
                return View(docs);    
        }
        #endregion

        #region Validations
        /// <summary>
        /// Método que se encarga de validar los parámetros de entrada en los campos
        /// de búsqueda de documentos, 
        /// </summary>
        /// <returns>Si se encuentran TODOS vacíos retorna verdadero
        /// al contrario retorna falso</returns>
        public bool IsDocSearchParamsEmpty(string userSender, string userReciever, string department, string docType, DateTime issueDate, DateTime receptionDate)
        {
            if (String.IsNullOrEmpty(userSender) && String.IsNullOrEmpty(userReciever) && String.IsNullOrEmpty(department) && String.IsNullOrEmpty(docType) && String.IsNullOrEmpty(issueDate.ToString()) && String.IsNullOrEmpty(receptionDate.ToString()))
                return true;
            else
                return false;
        }
        #endregion

    }
}
